#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "Config.h"

/*
 *  Function:  vClearBlank
 *
 *      To remove all comment and blank char from one line
 *
 *  Parameters:
 *
 *      vspLine IO- point of a string of a line
 *
 *  Return Value:
 *      none
 */
void vClearBlank(char *vspLine)
{
    int   i = 0, j, k;
    char    buf[_POSIX_MAX_INPUT];

    while (vspLine[i] != 0) {
        if (vspLine[i] == PFL_MEMO_CHARACTER || vspLine[i] == '\n') {
            vspLine[i] = 0;
            if (i == 0) break;
            j = i - 1;
            do {
                if (j < 0) break;
                if ((vspLine[j] != ' ') && (vspLine[j] != '\t')) break;
                vspLine[j--] = 0;
            } while(1);
            break;
        }
        i++;
    }

    i = 0;
    memset(buf, 0, _POSIX_MAX_INPUT);

    while ((vspLine[i] != '=') && (i < (int)strlen(vspLine)))
        i++;
    if (i == (int)strlen(vspLine)) return;

    for (j = i - 1; (vspLine[j] == ' ') || (vspLine[j] == '\t'); j--);
    for (k = i + 1; (vspLine[k] == ' ') || (vspLine[k] == '\t'); k++);

    memcpy(buf, vspLine, j + 1);
    buf[j + 1] = '=';
    strcat(buf + j + 2, vspLine + k);

    strcpy(vspLine, buf);
}


/*
 *  Function:  nIsSection
 *
 *      To confirm if a line is a section line
 *
 *  Parameters:
 *
 *      vspLine I - point of a string of a line
 *
 *  Return Value:
 *
 *       0 - is not a section line
 *       1 - is a section line
 */

int nIsSection(char * vspLine)
{
    return vspLine[0] == '[';
}


/*
 *  Function:  nIsThisSection
 *
 *      To confirm if this line is a spec section
 *
 *  Parameters:
 *
 *      vspLine    I - point of a string of a line
 *      vspSection I - name of section
 *
 *  Return Value:
 *
 *       0 - is not this section
 *       1 - is this section
 */

int nIsThisSection(const char *vspLine, const char *vspSection)
{
    return !memcmp(vspLine + 1, vspSection, strlen(vspSection));
}


/*
 *  Function:  nIsThisEntry
 *
 *      To confire if this line is a spec entry
 *
 *  Parameters:
 *
 *      vspLine  I - point of a string of a line
 *      vspEntry I - name of entry
 *
 *  Return Value:
 *
 *       0 - is not this entry
 *       1 - is this entry
 */

int nIsThisEntry(const char *vspLine, const char *vspEntry)
{
    return (!memcmp(vspLine, vspEntry, strlen(vspEntry)) &&
            vspLine[strlen(vspEntry)] == '=') ;
}


/*
 *  Function:  vCutContent
 *
 *      To get the value from a line
 *
 *  Parameters:
 *
 *      vspLine  I - point of a string of a line
 *      vspDest  O - value of entry to put
 *
 *  Return Value:
 *      none
 */

void vCutContent(char *vspLine, char *vspDest)
{
    int i = 0;

    while (vspLine[i++] != '=');

    strcpy(vspDest, vspLine + i);
}


/*
 *  Function:  nPflGetAttr
 *
 *      To get a string value from profile
 *
 *  Parameters:
 *
 *      vspSection  I - section name
 *      vspFilename I - full filename of profile
 *
 *  Return Value:
 *
 *      0 - success
 *      -1 - failure
 */

ANode* nPflGetAttr(const char *vspSection,
        const char *vspFilename)
{
    FILE    *fp;
    char    saLine[_POSIX_MAX_INPUT];
    int   cbNum = FALSE;
    int   InThisSection = FALSE;
    int   i = 0;
    ANode *vspValue, *pAnode;
    char  cVal[128];

    memset(cVal, 0 ,sizeof(cVal));
    if ((fp = fopen(vspFilename, "r")) == NULL) {
        return NULL;
    }

    vspValue = (ANode *)malloc(sizeof(ANode));
    pAnode = vspValue;

    while (NULL != fgets(saLine, _POSIX_MAX_INPUT, fp)) {
        vClearBlank(saLine);

        if (nIsSection(saLine)) {
            InThisSection = nIsThisSection(saLine, vspSection);
            if(InThisSection == TRUE)
            {
                i++;
                if (i>1)
                {
                    pAnode->NextMeb = (ANode *)malloc(sizeof(ANode));
                    pAnode = pAnode->NextMeb;
                }
            }
            continue;
        }

        if (InThisSection == FALSE) continue;

        if (nIsThisEntry(saLine, "ID")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->AId = atoi(cVal);
        }

        if (nIsThisEntry(saLine, "NAME")) {
            vCutContent(saLine, pAnode->AName);
        }
        if (nIsThisEntry(saLine, "TYPE")) {
            vCutContent(saLine, pAnode->AType);
        }
        if (nIsThisEntry(saLine, "LEN")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->ALen = atoi(cVal);
        }
        if (nIsThisEntry(saLine, "OFFSET")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->Aoffset = atoi(cVal);
        }
        if (nIsThisEntry(saLine, "TFUN")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->pfunc = SimComp;
        }
        if (nIsThisEntry(saLine, "ISCLASS")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->AisClass = atoi(cVal);
        }
        if (nIsThisEntry(saLine, "PNEED")) {
        memset(cVal, 0 ,sizeof(cVal));
            vCutContent(saLine, cVal);
            pAnode->APneed = atoi(cVal);
        }
    }

    fclose(fp);

    return vspValue;
}

int nPflGetString(const char *vspSection,
    const char *vspEntry,
    const char *vspFilename,
    char *vspValue)
{
    FILE    *fp;
    char    saLine[_POSIX_MAX_INPUT];
    int   cbNum = FALSE;
    int   InThisSection = FALSE;

    if ((fp = fopen(vspFilename, "r")) == NULL) {
    return FAILURE;
    }

    while (NULL != fgets(saLine, _POSIX_MAX_INPUT, fp)) {
    vClearBlank(saLine);

    if (nIsSection(saLine)) {
        InThisSection = nIsThisSection(saLine, vspSection);
        continue;
    }

    if (InThisSection == FALSE) continue;

    if (nIsThisEntry(saLine, vspEntry)) {
        vCutContent(saLine, vspValue);
        cbNum = TRUE;
        break;
    }
    }

    fclose(fp);

    if (cbNum == FALSE) {
    return FAILURE;
    }

    return SUCCESS;
}

/*
 *  Function:  nPflGetInt
 *
 *      To get a int value from profile
 *
 *  Parameters:
 *
 *      vspSection  I - section name
 *      vspEntry    I - entry name
 *      vspFilename I - full filename of profile
 *      vtpValue    O - pointer of int which value is returned
 *
 *  Return Value:
 *
 *      0 - success
 *      -1 - failure
 */

int nPflGetInt(const char *vspSection,
        const char *vspEntry,
        const char *vspFilename,
        int *vtpValue)
{
    char buf[_POSIX_MAX_INPUT];

    if (nPflGetString(vspSection, vspEntry, vspFilename, buf) != SUCCESS) {
        *vtpValue = 0;
        return FAILURE;
    }
    else {
        *vtpValue = atoi(buf);
        return SUCCESS;
    }
}

/*
 *  Function:  nPflGetShort
 *
 *      To get a int value from profile
 *
 *  Parameters:
 *
 *      vspSection  I - section name
 *      vspEntry    I - entry name
 *      vspFilename I - full filename of profile
 *      vtpValue    O - pointer of int which value is returned
 *
 *  Return Value:
 *
 *      0 - success
 *      -1 - failure
 */

int nPflGetShort(const char *vspSection,
        const char *vspEntry,
        const char *vspFilename,
        int *vnpValue)
{
    char buf[_POSIX_MAX_INPUT];

    if (nPflGetString(vspSection, vspEntry, vspFilename, buf) != SUCCESS) {
        *vnpValue = 0;
        return FAILURE;
    }
    else {
        *vnpValue = atoi(buf);
        return SUCCESS;
    }
}

/*
 *  Function: nPflGetLong
 *
 *      To get a long value from profile
 *
 *  Parameters:
 *
 *      vspSection  I - section name
 *      vspEntry    I - entry name
 *      vspFilename I - full filename of profile
 *      vlpValue    O - pointer of long which value is returned
 *
 *  Return Value:
 *
 *      0 - success
 *      -1 - failure
 */
int nPflGetLong(const char *vspSection,
        const char *vspEntry,
        const char *vspFilename,
        int *vlpValue)
{
    char buf[_POSIX_MAX_INPUT];

    if (nPflGetString(vspSection, vspEntry, vspFilename, buf) != SUCCESS) {
        *vlpValue = 0L;
        return FAILURE;
    }
    else {
        *vlpValue = atol(buf);
        return SUCCESS;
    }
}

char *spLtrim( char *vspStr )
{
    char *j;

    j = vspStr + strlen(vspStr);
    if (strlen(vspStr) == 0)
        return(vspStr);
    while ((vspStr[0] == ' ') && (vspStr < j))
        vspStr++;
    return(vspStr);
}

char *spRtrim(char *vspStr)
{
    int j;

    j = strlen(vspStr);
    if (j <=0)
        return(vspStr);
    while ((j != 0) && (vspStr[j-1] == ' '))
        j--;
    vspStr[j]='\0';
    return(vspStr);

}

char *spAlltrim(char *vspStr)
{
    return(spRtrim(spLtrim(vspStr)));
}
